What is require-in-the-middle?
The require-in-the-middle package allows for the interception and modification of Node.js module loading. This can be particularly useful for instrumentation, logging, or modifying module behavior at runtime without altering the original module code.
What are require-in-the-middle's main functionalities?
Intercepting module loading
This feature allows you to intercept the loading of specific modules (e.g., 'http') and execute custom logic, such as logging when a module is loaded. The callback function receives the exports of the module, the name of the module, and the base directory.
const hook = require('require-in-the-middle');
hook(['http'], { internals: true }, (exports, name, basedir) => {
console.log(`Module loaded: ${name}`);
return exports;
});
Modifying module exports
This demonstrates how to modify the exports of a module, in this case, 'express'. It wraps the original express function in a new function that logs a message every time it is called before proceeding with the original behavior.
const hook = require('require-in-the-middle');
hook(['express'], (exports, name) => {
const originalFunction = exports;
function modifiedFunction() {
console.log('Express function called');
return originalFunction.apply(this, arguments);
}
return modifiedFunction;
});
Other packages similar to require-in-the-middle
shimmer
Shimmer is a package for wrapping and replacing Node.js module methods. It is similar to require-in-the-middle in its ability to modify module behavior at runtime, but it focuses more on individual method manipulation rather than intercepting module loading.
proxyquire
Proxyquire allows for the overriding of modules during testing by intercepting 'require' calls. It is similar to require-in-the-middle in that it manipulates module loading, but it is specifically designed for testing scenarios, making it easier to mock modules.
require-in-the-middle
Hook into the Node.js require
function. This allows you to modify
modules on-the-fly as they are being required.
Also supports hooking into calls to process.getBuiltinModule()
, which was introduced in Node.js v22.3.0.
Installation
npm install require-in-the-middle --save
Usage
const path = require('path')
const { Hook } = require('require-in-the-middle')
new Hook(['express', 'mongodb'], function (exports, name, basedir) {
const version = require(path.join(basedir, 'package.json')).version
console.log('loading %s@%s', name, version)
exports._version = version
return exports
})
API
The require-in-the-middle module exposes a single function:
hook = new Hook([modules][, options], onrequire)
When called a hook
object is returned.
Arguments:
modules
<string[]> An optional array of module names to limit which modules
trigger a call of the onrequire
callback. If specified, this must be the
first argument. Both regular modules (e.g. react-dom
) and
sub-modules (e.g. react-dom/server
) can be specified in the array.options
<Object> An optional object containing fields that change when the
onrequire
callback is called. If specified, this must be the second
argument.
options.internals
<boolean> Specifies whether onrequire
should be called
when module-internal files are loaded; defaults to false
.
onrequire
<Function> The function to call when a module is required.
The onrequire
callback will be called the first time a module is
required. The function is called with three arguments:
exports
<Object> The value of the module.exports
property that would
normally be exposed by the required module.name
<string> The name of the module being required. If options.internals
was set to true
, the path of module-internal files that are loaded
(relative to basedir
) will be appended to the module name, separated by
path.sep
.basedir
<string> The directory where the module is located, or undefined
for core modules.
Return the value you want the module to expose (normally the exports
argument).
hook.unhook()
Removes the onrequire
callback so that it will not be triggerd by
subsequent calls to require()
or process.getBuiltinModule()
.
License
MIT